package tcp

import (
	"errors"
	"github.com/sirupsen/logrus"
	"lib/structs/base"
	"lib/structs/enum"
	"net"
	"sync"
)

var TcpServer *Server

type Server struct {
	clientMap   map[string]*Client
	clientMutex sync.Mutex
}

// SendInstruct 给特定客户端发送指令
func (s *Server) SendInstruct(clientId string, in base.ClientInstruct) (err error) {
	if _, ok := s.clientMap[clientId]; !ok {
		err = errors.New("客户端不在线")
		return err
	}
	err = s.clientMap[clientId].WriteMessage(in)
	return err
}

// IsOnline 检查客户都是否在线
func (s *Server) IsOnline(clientId string) (b bool) {
	_, b = s.clientMap[clientId]
	return b
}

/////////////////////////////////////

///////////////////// Server 代码  /////////////////////////////////

func NewServer(serAddr string) (err error) {
	TcpServer = &Server{
		clientMap:   make(map[string]*Client),
		clientMutex: sync.Mutex{},
	}
	err = TcpServer.start(serAddr)
	return
}

func (s *Server) start(serAddr string) (err error) {
	var (
		listener net.Listener
	)
	listener, err = net.Listen("tcp", serAddr)
	defer listener.Close()
	if err != nil {
		return err
	}
	logrus.Infof("启动tcp服务：%s", serAddr)
	for {
		var con net.Conn
		con, err = listener.Accept()
		if err != nil {
			logrus.Errorf("客户端连接失败：%s", err)
			continue
		}
		client := &Client{
			Conn:      con,
			inChan:    make(chan base.AmsResponse, 1000),
			outChan:   make(chan base.ClientInstruct, 1000),
			closeChan: make(chan byte, 1),
			mutex:     sync.Mutex{},
			IsClosed:  false,
			tcpServer: s,
		}
		logrus.Debugf("客户上线")
		go client.readLoop()
		go client.writeLoop()
		// 开启协程，监听客户端消息
		go client.handMsg()
	}
}

func (s *Server) Ping() {
	for _, v := range s.clientMap {
		msg := base.ClientInstruct{
			Type: enum.Ping,
		}
		_ = v.WriteMessage(msg)
	}
}
